package com.sfx.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sfx.domain.ResponseResult;
import com.sfx.domain.entity.Category;
import com.sfx.domain.vo.ArticleListVo;
import com.sfx.domain.vo.ArticleVo;
import com.sfx.domain.vo.HotArticleVo;
import com.sfx.domain.vo.PageVo;
import com.sfx.service.CategoryService;
import com.sfx.utils.BeanCopyUtils;
import com.sfx.utils.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sfx.mapper.ArticleMapper;
import com.sfx.domain.entity.Article;
import com.sfx.service.ArticleService;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.sfx.constants.RedisConstants.ARTICLE_VIEWCOUNT_KEY;
import static com.sfx.constants.SystemConstants.*;

/**
* Created with IntelliJ IDEA.
* Description:
* User: sfx
* Date: 2023-07-10
* Time: 11:00
*/
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService{

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private RedisCache redisCache;


    /**
     * 查询观看量最高的热门文章,最高10条
     * 不能把草稿展示出来，不能把删除了的文章查询出来。要按照浏览量进行降序排序。
     *
     * @return
     */
    @Override
    public ResponseResult hotArticleList() {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        //1.查询的文章必须是已经发布的状态
        queryWrapper.eq(Article::getStatus,ARTICLE_STATUS_NORMAL);
        //2.要按照浏览量进行降序排序。
        queryWrapper.orderByDesc(Article::getViewCount);
        //3.分页查询10条
        Page<Article> page = new Page<>(ARTICLE_PAGE_CURRENT,ARTICLE_PAGE_SIZE);
        //4.分页查询
        page(page,queryWrapper);
        //5.得到所有的查询记录
        List<HotArticleVo> vo = BeanCopyUtils.copyBeanList(page.getRecords(), HotArticleVo.class);
        return ResponseResult.okResult(vo);
    }
    /**
     * 查询文章分页列表
     * @return
     */
    @Override
    public ResponseResult articleList(Integer pageNum, Integer pageSize, Long categoryId) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        //1.查询分类文章列表(如果有分类的话)
        queryWrapper.eq(ObjectUtil.isNotNull(categoryId)&&categoryId>0, Article::getCategoryId,categoryId);
        //3.文章是正常发布状态的
        queryWrapper.eq(Article::getStatus, ARTICLE_STATUS_NORMAL);
        //2.按照置顶排序
        queryWrapper.orderByDesc(Article::getIsTop);
        //4.分页查询
        Page<Article> page = new Page<>(pageNum,pageSize);
        page(page,queryWrapper);
        List<Article> records = page.getRecords();

        //5.将每一个VO对象都设置对应的categoryName属性
        records = records.stream().map
                        (article -> article.setCategoryName(categoryService.getById(article.getCategoryId()).getName()))
                        .collect(Collectors.toList());
        //把文章的分类ID拿到,得到分类名称给他设置进去
        for (Article article : records) {
            Map<String, Integer> cacheMap = redisCache.getCacheMap(ARTICLE_VIEWCOUNT_KEY);
            Long viewCount = cacheMap.get(article.getId().toString()).longValue();
            article.setViewCount(viewCount);
        }

        //6.封装成VO对象
        List<ArticleListVo> articleListVos = BeanCopyUtils.copyBeanList(records, ArticleListVo.class);
        //7.封装成PageVO
        PageVo pageVo = new PageVo();
        pageVo.setRows(articleListVos);
        pageVo.setTotal(page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    /**
     * 查询文章详情
     * @param id
     * @return
     */
    @Override
    public ResponseResult getArticleById(Integer id) {
        Article article = getById(id);
        Map<String, Integer> cacheMap = redisCache.getCacheMap(ARTICLE_VIEWCOUNT_KEY);
        Long viewCount = cacheMap.get(id.toString()).longValue();
        article.setViewCount(viewCount);
        Category category = categoryService.getById(article.getCategoryId());
        if(category.getName() != null) {
            article.setCategoryName(category.getName());
        }
        ArticleVo articleVO = BeanCopyUtils.copyBean(article, ArticleVo.class);
        return ResponseResult.okResult(articleVO);
    }

    /**
     * 更新博客浏览量
     * @param id
     * @return
     */
    @Override
    public ResponseResult updateViewCount(Long id) {
        //更新浏览量的时候去更新redis中的数据
        //每次都增加浏览量1
        redisCache.increment(ARTICLE_VIEWCOUNT_KEY,id.toString(),1L);
        return ResponseResult.okResult();
    }
}